{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_lfw_pairs\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "from deepface import DeepFace\n",
    "from tqdm import tqdm\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#lfw_people = fetch_lfw_people()\n",
    "fetch_lfw_pairs = fetch_lfw_pairs(subset = 'test', color = True\n",
    "                                  , resize = 1 #this transform inputs to (125, 94) from (62, 47)\n",
    "                                 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "pairs = fetch_lfw_pairs.pairs\n",
    "labels = fetch_lfw_pairs.target\n",
    "target_names = fetch_lfw_pairs.target_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "instances:  1000\n"
     ]
    }
   ],
   "source": [
    "instances = pairs.shape[0]\n",
    "print(\"instances: \", instances)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dlib loaded\n"
     ]
    }
   ],
   "source": [
    "from deepface.basemodels import VGGFace, Facenet, OpenFace, FbDeepFace\n",
    "from deepface.basemodels.DlibResNet import DlibResNet\n",
    "\"\"\"vgg_model = VGGFace.loadModel()\n",
    "print(\"VGG-Face loaded\")\n",
    "\n",
    "facenet_model = Facenet.loadModel()\n",
    "print(\"FaceNet loaded\")\n",
    "\n",
    "openface_model = OpenFace.loadModel()\n",
    "print(\"OpenFace loaded\")\n",
    "\n",
    "deepface_model = FbDeepFace.loadModel()\n",
    "print(\"DeepFace loaded\")\n",
    "\n",
    "\"\"\"\n",
    "dlib_model = DlibResNet()\n",
    "print(\"Dlib loaded\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1000/1000 [03:32<00:00,  4.70it/s]\n"
     ]
    }
   ],
   "source": [
    "plot = False\n",
    "\n",
    "actuals = []; predictions = []; distances = []\n",
    "\n",
    "pbar = tqdm(range(0, instances))\n",
    "\n",
    "for i in pbar:\n",
    "    pair = pairs[i]\n",
    "    img1 = pair[0]; img2 = pair[1]\n",
    "    img1 = img1[:,:,::-1]; img2 = img2[:,:,::-1] #opencv expects bgr instead of rgb\n",
    "    \n",
    "    #obj = DeepFace.verify(img1, img2, model_name = 'VGG-Face', model = vgg_model)\n",
    "    obj = DeepFace.verify(img1, img2, model_name = 'Dlib', model = dlib_model, distance_metric = 'euclidean', enforce_detection=False)\n",
    "    prediction = obj[\"verified\"]\n",
    "    predictions.append(prediction)\n",
    "    \n",
    "    distances.append(obj[\"distance\"])\n",
    "    \n",
    "    label = target_names[labels[i]]\n",
    "    actual = True if labels[i] == 1 else False\n",
    "    actuals.append(actual)\n",
    "    \n",
    "    if plot:    \n",
    "        print(i)\n",
    "        fig = plt.figure(figsize=(5,2))\n",
    "\n",
    "        ax1 = fig.add_subplot(1,3,1)\n",
    "        plt.imshow(img1/255)\n",
    "        plt.axis('off')\n",
    "\n",
    "        ax2 = fig.add_subplot(1,3,2)\n",
    "        plt.imshow(img2/255)\n",
    "        plt.axis('off')\n",
    "\n",
    "        ax3 = fig.add_subplot(1,3,3)\n",
    "        plt.text(0, 0.50, label)\n",
    "        plt.axis('off')\n",
    "\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "accuracy = 100*accuracy_score(actuals, predictions)\n",
    "precision = 100*precision_score(actuals, predictions)\n",
    "recall = 100*recall_score(actuals, predictions)\n",
    "f1 = 100*f1_score(actuals, predictions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "instances:  1000\n",
      "accuracy:  92.7 %\n",
      "precision:  94.20289855072464 %\n",
      "recall:  91.0 %\n",
      "f1:  92.5737538148525 %\n"
     ]
    }
   ],
   "source": [
    "print(\"instances: \",len(actuals))\n",
    "print(\"accuracy: \" , accuracy, \"%\")\n",
    "print(\"precision: \", precision, \"%\")\n",
    "print(\"recall: \", recall,\"%\")\n",
    "print(\"f1: \",f1,\"%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "cm = confusion_matrix(actuals, predictions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[472,  28],\n",
       "       [ 45, 455]], dtype=int64)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "tn, fp, fn, tp = cm.ravel()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(472, 28, 45, 455)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(tn, fp, fn, tp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "true_negative = 472\n",
    "false_positive = 28\n",
    "false_negative = 45\n",
    "true_positive = 455"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
